/*
 *  Copyright © OpenAtom Foundation.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.openatom.ubml.model.be.definition.operation;

import java.util.EnumSet;
import org.openatom.ubml.model.be.definition.beenum.BEDeterminationType;
import org.openatom.ubml.model.be.definition.beenum.BEOperationType;
import org.openatom.ubml.model.be.definition.beenum.BETriggerTimePointType;
import org.openatom.ubml.model.be.definition.beenum.RequestNodeTriggerType;
import org.openatom.ubml.model.be.definition.collection.DtmElementCollection;

/**
 * The Definition Of Determination
 *
 * @ClassName: Determination
 * @Author: Benjamin Gong
 * @Date: 2021/1/11 17:13
 * @Version: V1.0
 */
public class Determination extends BizOperation implements Cloneable {

    // region 字段

    private DtmElementCollection rqtElements;
    private java.util.HashMap<String, DtmElementCollection> requestChildElements;

    // private java.util.HashMap<BETriggerTimePointType, String> preDtmId;

    // endregion

    // region 构造函数
    /**
     * Determination类型
     */
    private BEDeterminationType privateDeterminationType = BEDeterminationType.forValue(0);

    // endregion

    // region 属性
    /**
     * 触发时机的类型
     */
    private EnumSet<BETriggerTimePointType> privateTriggerTimePointType = EnumSet.of(BETriggerTimePointType.forValue(0));
    /**
     * Node状态触发时机的类型
     */
    private EnumSet<RequestNodeTriggerType> privateRequestNodeTriggerType = EnumSet
            .of(RequestNodeTriggerType.forValue(0));

    /**
     * 默认构造函数
     */
    public Determination() {
    }

    /**
     * 操作类型
     */
    @Override
    public BEOperationType getOpType() {
        return BEOperationType.Determination;
    }

    public final BEDeterminationType getDeterminationType() {
        return privateDeterminationType;
    }

    public final void setDeterminationType(BEDeterminationType value) {
        privateDeterminationType = value;
    }

    public final EnumSet<BETriggerTimePointType> getTriggerTimePointType() {
        return privateTriggerTimePointType;
    }

    public final void setTriggerTimePointType(EnumSet<BETriggerTimePointType> value) {
        privateTriggerTimePointType = value;
    }

    public final EnumSet<RequestNodeTriggerType> getRequestNodeTriggerType() {
        return privateRequestNodeTriggerType;
    }

    public final void setRequestNodeTriggerType(EnumSet<RequestNodeTriggerType> value) {
        privateRequestNodeTriggerType = value;
    }

    public final DtmElementCollection getRequestElements() {
        if (rqtElements == null) {
            rqtElements = new DtmElementCollection();
        }
        return rqtElements;
    }

    /**
     * 触发时变更集中需要包含的字段LabelID集合
     */
    public final void setRequestElements(DtmElementCollection value) {
        rqtElements = value;
    }

    public final java.util.HashMap<String, DtmElementCollection> getRequestChildElements() {
        if (requestChildElements == null) {
            requestChildElements = new java.util.HashMap<String, DtmElementCollection>();
        }
        return requestChildElements;
    }

    public final void setRequestChildElements(java.util.HashMap<String, DtmElementCollection> value) {
        requestChildElements = value;
    }

    // /**
    // * 获取当前计算规则的前置计算规则
    // *
    // * 根据元数据设计器上配置的计算顺序生成的当前计算规则的前置规则
    // */
    // public final java.util.HashMap<BETriggerTimePointType, String> getPreDtmId()
    // {
    // if (preDtmId == null) {
    // preDtmId = new java.util.HashMap<BETriggerTimePointType, String>();
    // }
    // return preDtmId;
    // }

    // endregion

    // region 方法

    /**
     * 判断是否相等
     *
     * @param obj 与当前联动规则比较的对象
     * @return 相等返回true
     */
    @Override
    public boolean equals(Object obj) {
        Determination other = (Determination)((obj instanceof Determination) ? obj : null);
        return other != null && ((this == other) || equals(other));
    }

    /**
     * 重写Equals
     *
     * @param other
     * @return
     */
    protected final boolean equals(Determination other) {
        return super.equals(other) && getDeterminationType() == other.getDeterminationType()
                && getTriggerTimePointType() == other.getTriggerTimePointType()
                && other.getRequestNodeTriggerType() == getRequestNodeTriggerType();

    }

    /**
     * 重写 GetHashCode
     *
     * @return
     */
    @Override
    public int hashCode() {
        {
            int hashCode = (super.hashCode() * 397);
            hashCode = (hashCode * 397) ^ getDeterminationType().hashCode();
            hashCode = (hashCode * 397) ^ getTriggerTimePointType().hashCode();
            hashCode = (hashCode * 397) ^ getRequestNodeTriggerType().hashCode();
            return hashCode;
        }
    }

    /**
     * Clone方法
     *
     * @param isGenerateId
     * @return
     */
    @Override
    public Determination clone(boolean isGenerateId) {
        Object tempVar = super.clone(isGenerateId);
        Determination result = (Determination)((tempVar instanceof Determination) ? tempVar : null);
        return result;
    }

    public final void mergeWithDependentDetermination(Determination dependentDetermination) {
        if (getIsRef() || dependentDetermination == null) {
            return;
        }
        mergeOperationBaseInfo(dependentDetermination);
        mergeDeterminationInfo(dependentDetermination);
    }

    private void mergeDeterminationInfo(Determination dependentDetermination) {
        setDeterminationType(dependentDetermination.getDeterminationType());
        setTriggerTimePointType(dependentDetermination.getTriggerTimePointType());
        setRequestNodeTriggerType(dependentDetermination.getRequestNodeTriggerType());

        for (String requestElement : dependentDetermination.getRequestElements()) {
            getRequestElements().add(requestElement);
        }

        // for (String item : dependentDetermination.getPreDtmId()) {
        // getPreDtmId().put(item.getKey(), item.getValue());
        // }
    }

    // endregion

}